<?php

declare(strict_types=1);

namespace App\AdminApi\Module\Admin\Api;

use App\AdminApi\AdminApiBasicsController;
use App\AdminApi\Module\Admin\Service\UserService;
use App\AdminApi\Module\Admin\Validate\UserValidate;
use App\Sys;
use Hyperf\Database\Model\Relations\HasOne;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\{Controller, GetMapping, PostMapping, RequestMapping};
use Psr\Http\Message\ResponseInterface;
use Psr\SimpleCache\InvalidArgumentException;
use Zms\AdminElementPlus\FormCreate\ElemenuForm;
use Zms\Guard\Auth;
use Zms\HyperfResponse\Response;
use Zms\HyperfValidateAnnotations\Validate;
use Zms\Unit\Is;
use Zms\Unit\Str;

#[
    Controller(prefix: "/admin-api/admin-user", server: self::SERVER),
    Auth(guard: self::GUARD, label: ['后台管理', '管理员'], app: self::APP)
]
class UserController extends AdminApiBasicsController
{
    #[Inject]
    protected UserService $service;


    #[
        GetMapping('list'),
        Auth(sign: 'admin.user.list', describe: "查看管理员", view: '/admin/user/index')
    ]
    public function list(): ResponseInterface
    {
        $where = $this->request->inputs(['id', 'nickname', 'status', 'is_super', 'department_id', 'job_id']);
        if (!(isset($where['id']) && Is::notEmpty($where['id']))) {
            $where['id'] = $this->dataAuth();
        }
        $paginate = $this->service->search($where)
            ->with([
                'department' => function (HasOne $query) {
                    $query->select(['id', 'name']);
                },
                'job' => function (HasOne $query) {
                    $query->select(['id', 'name']);
                }
            ])
            ->selectRaw("*,'' as `line`")
            ->orderByRaw($this->orderBy('id<>1,id DESC'))
            ->paginate($this->pageSize());
        return Response::Api()->success(data: $paginate);
    }


    #[
        RequestMapping('created'),
        Auth(sign: 'admin.user.created', logger: 'POST'),
        ElemenuForm(class: UserService::class, function: "createdUserForm"),
        Validate(class: UserValidate::class, scene: "created")
    ]
    public function created(): ResponseInterface
    {
        $data = $this->request->getParsedBody();
        if ($this->service->created($data)) {
            return Response::Api()->success('添加成功');
        }
        return Response::Api()->fail('添加失败');
    }


    #[
        RequestMapping('updated'),
        Auth(sign: 'admin.user.updated', logger: 'POST'),
        ElemenuForm(class: UserService::class, function: "updatedUserForm", param: ['id']),
        Validate(class: UserValidate::class, scene: "updated")
    ]
    public function updated(): ResponseInterface
    {
        $data = $this->request->getParsedBody();
        if ($this->service->updated($data)) {
            return Response::Api()->success('帐号编辑成功');
        }
        return Response::Api()->fail('帐号编辑失败');
    }


    #[
        PostMapping('created-code'),
        Auth(label: ['生成授权码'], sign: 'admin.user.code')
    ]
    public function createdCode(): ResponseInterface
    {
        $id = (int)$this->request->input('id', 0);
        $state = $this->service->checkAccountStatus($id);//检测账号状态
        if ($state !== true) {
            return Response::Api()->fail($state);
        }
        $code = Str::md5_16(time(), rand(1000, 9999), rand(1000, 9999));
        try {
            Sys::cache()->set($code, $id, 180);
            return Response::Api()->success(data: ['code' => $code, 'exp' => 180, 'end' => time() + 180]);
        } catch (InvalidArgumentException) {
            return Response::Api()->fail('生成授权码失败');
        }
    }


    #[
        PostMapping('status'),
        Auth(relyon: ["admin.user.updated"], logger: false, describe: '更改会员状态'),
        Validate(rules: \Zms\Constants\Validate::CHANGE_STATUS_RULES)
    ]
    public function status(): ResponseInterface
    {
        $data = $this->request->inputs(['id', 'status']);
        if ($this->service->isRootUser((int)$data['id'])) {
            return Response::Api()->fail('不能操作根账号');
        }
        if ($this->service->search(['id' => $data['id']])->update(['status' => $data['status']])) {
            return Response::Api()->success('更改成功');
        }
        return Response::Api()->fail('更改失败');
    }


    #[
        PostMapping('locking'),
        Auth(label: ['锁定帐号'], sign: "admin.user.locking"),
        Validate(rules: [
            ['id', 'required', 'error' => '请选择要锁定的账号']
        ])
    ]
    public function locking(): ResponseInterface
    {
        $id = (int)$this->request->input('id') ?: 0;
        if ($this->service->isRootUser($id)) {
            return Response::Api()->fail('不能锁定主账号');
        }
        if ($this->service->search(['id' => $id])->update(['locking' => time() + 315360000])) {
            return Response::Api()->success('帐号已锁定');
        }
        return Response::Api()->fail('锁定失败');
    }


    #[
        PostMapping('unlock'),
        Auth(label: ['解锁帐号'], sign: "admin.user.unlock"),
        Validate(rules: [
            ['id', 'required', 'error' => '请选择要锁定的账号']
        ])
    ]
    public function unlock(): ResponseInterface
    {
        $id = (int)$this->request->input('id') ?: 0;
        if ($this->service->search(['id' => $id])->update(['locking' => 0, 'error' => 0])) {
            return Response::Api()->success('帐号已解锁');
        }
        return Response::Api()->fail('解锁失败');
    }

    #[
        PostMapping('remove'),
        Auth(sign: 'admin.user.remove')
    ]
    public function remove(): ResponseInterface
    {
        $id = (int)$this->request->input('id', '0');
        if ($this->service->isRootUser($id)) {
            return Response::Api()->fail('禁止删除主账号');
        }
        if ($this->service->search(['id' => $id])->delete()) {
            return Response::Api()->success('帐号已删除');
        }
        return Response::Api()->fail('帐号删除失败');
    }
}